from decimal import Decimal

from django.db import transaction
from django.utils import timezone
from rest_framework import serializers
from django_redis import get_redis_connection
from goods.models import SKU
from orders.models import OrderInfo, OrderGoods


class OrderCommitSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ('order_id', 'address', 'pay_method')
        read_only_fields = ('order_id',)
        extra_kwargs = {
            'address': {
                'write_only': True,
                'required': True,
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }

    def create(self, validated_data):
        """

        """
        # 获取用户信息
        user = self.context['request'].user
        # 生成订单号
        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
        # 运费
        freight = Decimal('10.0')
        # 地址
        address = validated_data['address']
        # 支付方式
        pay_method = validated_data['pay_method']
        # 状态
        status = OrderInfo.ORDER_STATUS_ENUM['UNSEND'] if pay_method == OrderInfo.PAY_METHODS_ENUM[
            'CASH'] else OrderInfo.ORDER_STATUS_ENUM['UNPAID']
        with transaction.atomic():
            # 创建一个保存点
            save_id = transaction.savepoint()
        try:
            # 保存订单信息
            order_info = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_count=0,
                total_amount=Decimal('0'),
                freight=freight,
                pay_method=pay_method,
                status=status
            )
            # 从redis中获取订单商品信息
            redis_conn = get_redis_connection('cart')
            cart_redis = redis_conn.hgetall('cart_%s' % user.id)
            cart_select = redis_conn.smembers('cart_selected_%s' % user.id)
            cart = {}
            for sku_id in cart_select:
                cart[int(sku_id)] = int(cart_redis[sku_id])
                count = int(cart_redis[sku_id])
                # 获取商品信息
                sku = SKU.objects.get(pk=sku_id)
                # 判断库存是否足够
                if count > sku.stock:
                    raise serializers.ValidationError('库存不足')
                # 修改商品信息
                # sku.sales += count
                # sku.stock -= count
                # sku.save()

                origin_stock = sku.stock
                origin_sales = sku.sales

                new_sotck = origin_stock - count
                new_sales = origin_sales + count

                SKU.objects.filter(pk=sku_id, stock=origin_stock).update(stock=new_sotck, sales=new_sales)

                # 保存订单商品数据
                order_info.total_count += count
                order_info.total_amount += (sku.price * count)
                # 保存商品订单信息
                OrderGoods.objects.create(
                    order=order_info,
                    sku=sku,
                    count=count,
                    price=sku.price
                )

            order_info.save()
        except ValueError:
            raise

        except Exception as e:
            transaction.savepoint_rollback(save_id)
            raise serializers.ValidationError('下单失败')

        # 提交失误
        transaction.savepoint_commit(save_id)

        # 删除redis中的订单商品信息
        redis_conn.hdel('cart_%s' % user.id, *cart_select)
        redis_conn.srem('cart_selected_%s' % user.id, *cart_select)

        return order_info


class CartSKUSerializer(serializers.ModelSerializer):
    """
    购物车商品数据序列化器
    """
    count = serializers.IntegerField(label='数量')

    class Meta:
        model = SKU
        fields = ('id', 'name', 'default_image_url', 'price', 'count')


class OrderSettlementSerializer(serializers.Serializer):
    """
    订单结算数据序列化器
    """
    freight = serializers.DecimalField(label='运费', max_digits=10, decimal_places=2)
    skus = CartSKUSerializer(many=True)
